package routing.googleadapter;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

import com.google.android.gms.maps.model.LatLng;



/**
 * represents a KML-file from Google and is able to parse it
 * into a vector of Placemarks and to a JSON string
 * 
 * @author Alexander Münch (sialmuen)
 */
public class RouteKMLParser extends DefaultHandler {
	
	private String kmlData;
	private ArrayList <Landmark> landMarkList;
	
	public RouteKMLParser(InputStream xmlInput) {
		StringBuffer content = new StringBuffer();
		try {
			BufferedReader googleIn = new BufferedReader(new InputStreamReader(xmlInput, "UTF-8"));
			String b;
			
			while ((b = googleIn.readLine()) != null) content.append(b.trim());
			
			kmlData = content.toString();
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * @param xmlKmlData: full XML data
	 */
	public RouteKMLParser(String xmlKmlData) {
		kmlData = xmlKmlData;
		landMarkList = null;
	}

	
	/**
	 * returns a vector of KmlPlacemarks
	 * @return Vector of KmlPlacemarks
	 */
	public ArrayList<Landmark> getWaypoints() {
		if(landMarkList == null)
			parse();
		
		return landMarkList;
	}
	
	
	/**
	 * parses the data
	 */
	private void parse() {		
		DocumentBuilder dBuilder;
		Document document;
		Landmark currentLM;
		
		try {
			dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			document = dBuilder.parse(new InputSource(new StringReader(kmlData)));
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		}

		landMarkList = new ArrayList<Landmark>();
		NodeList placemarkNodes = document.getElementsByTagName("step");
		for(int i = 0; i < placemarkNodes.getLength(); i++) {
			Node placemarkNode = placemarkNodes.item(i);

			currentLM = new Landmark();
			landMarkList.add(currentLM);
			
			if(placemarkNode.hasChildNodes()) {
				Node child = placemarkNode.getFirstChild();
				do {
					String tagName = child.getNodeName();

					if (tagName.equals("location")) {
						currentLM.setLatLng(getCoordinates(child.getFirstChild()));
					}
					else if (tagName.equals("title")) {
						currentLM.setTitle(child.getFirstChild().getNodeValue());
						Log.d(this.getClass().getName(), currentLM.getTitle());
					}
					else if (tagName.equals("img")) currentLM.setSnapshotFilename(child.getFirstChild().getNodeValue());

					child = child.getNextSibling();
				} while(child != null);
			}
		}
	}
	
	private LatLng getCoordinates(Node pointChild) {
		double lat = 0, lng = 0;
		
		while(pointChild != null) {
			if(pointChild.getNodeName().equals("lat")) lat = Double.valueOf(pointChild.getTextContent());
			else if(pointChild.getNodeName().equals("lng")) lng = Double.valueOf(pointChild.getTextContent());

			pointChild = pointChild.getNextSibling();
		}
		
		return new LatLng(lat, lng);
	}
}
